using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using NUnit.Framework.Extensions;
using Mono.Graph;
using Mono.Boost.PriorityQueue;
namespace Mono.Graph.Tests
{
    [TestFixture]
    public class SpeedTests
    {


        int[] HeapSpeedSimple(IRangeIndexedPriorityQueue<int> Q, int seed)
        {
            int a = 1000000;
            Q.Create(a);
            int[] ret = new int[a];
            Random r = new Random(seed + 100);
            DateTime start = DateTime.Now;
            for (int i = 0, j = 0; i < a; i++)
            {
                int dod = r.Next() % 1000000000 + 100000000 - 10000 * i;
                Q.Insert(i, dod);
                if (r.Next() % 5 == 0) { Q.Pop(); ret[j++] = Q.TopVal; }
            }

            Console.WriteLine("Heap Spead of {0} for seed={1} is {2}",
                        Q.ToString(),
                        seed,
                        (TimeSpan)(DateTime.Now - start));
            return ret;
        }

        int[] HeapSpeedWithDecrease(IRangeIndexedPriorityQueue<int> Q, int seed)
        {
            int a = 10000;
            Q.Create(a);
            int[] ret = new int[a];
            Random r = new Random(seed );
            DateTime start = DateTime.Now;
            for (int i = 0, j = 0; i < a; i++)
            {
                Int64 ss = r.Next();
                int dod = (int)(ss % 1000000000 + 10000000 - i);
                Q.Insert(i, dod);
                for (int z = 0; z < i; z++)
                {
                    ss *= 123123;
                    ss += 1234567;
                    int newval = (int)(ss% 1000000000 +1000 - i*100000 - z );
                    ss = (Int64)newval;
                    Q.DecreaseKey(z,newval);
                }
                if (r.Next() % 5 == 0) {  ret[j++] = Q.TopVal;while(Q.TopVal==ret[j])Q.Pop(); }
            }

            Console.WriteLine("Heap Spead of {0} for seed={1} is {2}",
                        Q.ToString(),
                        seed,
                        (TimeSpan)(DateTime.Now - start));
            return ret;
        }

        [Test]
        public void SimpleRandomCorectness1000()
        {
            int a = 1000;
            Random r = new Random();
            IRangeIndexedPriorityQueue<int> PQ = new IndexedBinaryHeap<int>(a);
            int[] S = new int[a];
            for (int i = 0; i < a; i++)
            {
                int dod = r.Next() % 1000000000 + 1000000000;

                S[a - i - 1] = dod;
                Array.Sort(S);
                PQ.Insert(i, dod);
                Assert.AreEqual(PQ.TopVal, S[a - i - 1], "Index = " + i + "  PQ returns =" + PQ.TopVal + " Sort=" + S[a - i - 1]);
            }

        }
        [Test]
        public void SimpleSpeedCompare()
        {
            for (int j = 0; j < 1; j++)
            {
                Console.WriteLine("TEST " + j);
                int[] A1 = HeapSpeedSimple(new FibonacciHeap<int>(), j);
                int[] A2 = HeapSpeedSimple(new IndexedBinaryHeap<int>(), j);
                for (int i = 0; i < A1.Length; i++) Assert.AreEqual(A1[i], A2[i], "line [" + i + "] = " + A1[i] + ":" + A2[i]);
            }
        }
        [Test]
        [Explicit]
        public void SpeedCompare_DEC()
        {
            for (int j = 0; j < 10; j++)
            {
                Console.Write("TEST ");
//                int[] A1 = HeapSpeedWithDecrease(new IndexedBinaryHeapIntOLD(), j);
//                int[] A3 = HeapSpeedWithDecrease(new IndexedBinaryHeapInt(), j);
                int[] A1 = HeapSpeedWithDecrease(new FibonacciHeap<int>(), j);
                int[] A2 = HeapSpeedWithDecrease(new IndexedBinaryHeap<int>(), j);
                int[] A3 = HeapSpeedWithDecrease(new MyHeap<int>(), j);
                string[] B = new string [A1.Length];
                for (int i = 0; i < A1.Length; i++) B[i]= "F="+A1[i]+" B="+A2[i]+" my="+A3[i];
                
                for (int i = 0; i < A1.Length; i++)
                {
//                    Console.Write("line"+i);
                    Assert.AreEqual(A1[i], A2[i], "line [" + i + "] = " + A1[i] + ":" + A2[i] + "FIBONNACI(expected) : BINARY ");
                    Assert.AreEqual(A1[i], A3[i], "line [" + i + "] = " + A1[i] + ":" + A3[i] + "FIBONNACI(expected) : MY ");
//                    Console.Write("OK\n");
                }
 //               for (int i = 0; i < A1.Length; i++) Assert.AreEqual(A4[i], A3[i], "line [" + i + "] = " + A1[i] + ":" + A3[i]);
    //            for (int i = 0; i < A1.Length; i++) Assert.AreEqual(A4[i], A1[i], "line [" + i + "] = " + A1[i] + ":" + A4[i]);
            }
        }
    

    }
}